Skip to content

Optimize interleave boolean gather#8350

Merged
robert3005 merged 12 commits into
developfrom
claude/eager-heisenberg-fxi8wx
Jun 23, 2026
Merged

Optimize interleave boolean gather#8350
robert3005 merged 12 commits into
developfrom
claude/eager-heisenberg-fxi8wx

Conversation

@joseph-isaacs

@joseph-isaacs joseph-isaacs commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR optimizes the boolean gather path in InterleaveArray and adds comprehensive benchmarks comparing Vortex's implementation against arrow-rs across multiple access patterns.

@joseph-isaacs joseph-isaacs added the changelog/performance A performance improvement label Jun 11, 2026 — with Claude
@codspeed-hq

codspeed-hq Bot commented Jun 11, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 1579 untouched benchmarks
🆕 6 new benchmarks
⏩ 4 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Simulation vortex[random/n2/nonnull] N/A 132.9 µs N/A
🆕 Simulation vortex[random/n2/null] N/A 135.7 µs N/A
🆕 Simulation vortex[round_robin/n2/nonnull] N/A 136 µs N/A
🆕 Simulation vortex[round_robin/n2/null] N/A 135.1 µs N/A
🆕 Simulation vortex[random/n64/nonnull] N/A 183.2 µs N/A
🆕 Simulation vortex[random/n64/null] N/A 199.9 µs N/A

Comparing claude/eager-heisenberg-fxi8wx (12a1071) with develop (5a764e6)

Open in CodSpeed

Footnotes

  1. 4 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@joseph-isaacs joseph-isaacs changed the title Optimize interleave boolean gather and add comprehensive benchmarks Optimize interleave boolean gather Jun 17, 2026
@joseph-isaacs joseph-isaacs marked this pull request as ready for review June 17, 2026 13:45
@joseph-isaacs joseph-isaacs requested review from a team and AdamGS June 17, 2026 13:45
claude and others added 11 commits June 23, 2026 00:41
…terleave

Extends the interleave benchmark to measure the Vortex boolean execute path
against the arrow-rs `interleave` kernel on identical data, across three access
patterns (random, round_robin, single_branch), for N=2 and N=4 value arrays,
nullable and non-nullable.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…ecked reads

Profiling and disassembly of the gather inner loop showed the per-bit cost was
dominated not by the 64-bit packing (optimal for a random gather) but by the
overhead around each read: a wide `&[BitBuffer]` struct index, the redundant
bounds `assert` inside `BitBuffer::value`, and on the nullable path a per-row
`Option`/`Mask`-variant dispatch.

Pre-validate the per-row bounds once, then hoist a raw `(ptr, bit_offset)` per
value buffer and read each selected bit with `get_bit_unchecked`. Materialize
each branch's validity into one full-length `BitBuffer` so the validity gather
is the same uniform unchecked read. Measured ~1.2x faster non-nullable and
~1.4x nullable across random / round-robin / single-branch patterns.

Also adds two two-value word-boundary regression tests exercising the gather
across more than one 64-bit packing word, in the non-nullable and nullable
cases, validated against the existing scalar reference oracle.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Remove the arrow-rs `interleave` comparison arm and its input builder, keeping
the Vortex-only benchmark across the random / round_robin / single_branch
access patterns (N=2, N=4, nullable and non-nullable). No dependency changes:
every arrow crate in vortex-array is used by the crate's own source.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…ctor types

Drop the `AsPrimitive<usize>` bound on the bool gather: dispatch both selectors
over their concrete unsigned width via `match_each_unsigned_integer_ptype!` and
convert to an index with a plain `as usize` on the native type, passed in as
`branch_at` / `row_at` accessors. Keeps the selector loads at their native width.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Keep only 2-child round-robin, 2-child random, and 64-child random (each
nullable and non-nullable); drop the single_branch pattern and the N=4 variants.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…> selectors

Go back to the generic `gather<A: AsPrimitive<usize>, R: AsPrimitive<usize>>`
with `.as_()` conversions, dropping the per-type `as usize` accessors. The
trait conversion avoids the `cast_possible_truncation` lint without a scoped
allow and matches the idiom used by the other bool kernels (e.g. take).

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…tern

Replace `Combo.pattern: &'static str` and the `match`/`unreachable!` on string
literals with a `Pattern` enum (RoundRobin, Random), making the match exhaustive
and dropping the unreachable arms.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…lidity

Validity is just another set of boolean buffers routed by the same selectors, so
factor the hoisted-pointer unchecked gather into `gather_bits` and call it for
both the values and the materialized per-branch validity, instead of duplicating
the pointer-table build and `collect_bool` loop.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…tructor docs

The `new_unchecked` / `new_unchecked_slots` doc comments intra-doc-linked
`[`Interleave::check`]`, a private item, failing `rustdoc::private_intra_doc_links`
(`-D warnings`). Drop the link brackets, keeping the inline-code reference.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
@robert3005 robert3005 force-pushed the claude/eager-heisenberg-fxi8wx branch from e07d424 to aae3eae Compare June 22, 2026 23:41
`cargo +nightly fmt --all --check` (the Rust lint job's format step) requires
per-item imports; split `use vortex_array::{array_session, ArrayRef}`.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
@robert3005 robert3005 enabled auto-merge (squash) June 23, 2026 16:19
@robert3005 robert3005 merged commit dab39bf into develop Jun 23, 2026
64 checks passed
@robert3005 robert3005 deleted the claude/eager-heisenberg-fxi8wx branch June 23, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/performance A performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants